﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Softyum.ForexAgent
{
    static class HotKey
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="id"></param>
        /// <param name="fsModifiers"></param>
        /// <param name="vk"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, HotKeyModifiers fsModifiers, Keys vk);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        /// <summary>
        /// 
        /// </summary>
        private const int WM_HOTKEY = 0x312;
        
        /// <summary>
        /// 
        /// </summary>
        private static int keyid = 10;
        private static Dictionary<int, HotkeyCallback> keymap 
            = new Dictionary<int, HotkeyCallback>();

        public delegate void HotkeyCallback();

        public static void Register(IntPtr hWnd, HotKeyModifiers fsModifiers, Keys vk, HotkeyCallback callback)
        {
            int id = keyid++;
            if (!RegisterHotKey(hWnd, id, fsModifiers, vk))
                throw new Exception("Register hotkey failed");
            keymap[id] = callback;
        }

        public static void Register(IntPtr hWnd, String k, HotkeyCallback callback)
        {
            KeysConverter converter = new KeysConverter();
            Keys keys = (Keys)converter.ConvertFromString(k);
            HotKeyModifiers mods = 0;
            if ((keys & Keys.Control) == Keys.Control)
            {
                mods |= HotKeyModifiers.MOD_CONTROL;
            }
            if ((keys & Keys.Alt) == Keys.Alt)
            {
                mods |= HotKeyModifiers.MOD_ALT;
            }
            if ((keys & Keys.Shift) == Keys.Shift)
            {
                mods |= HotKeyModifiers.MOD_SHIFT;
            }
           
            keys = keys & ~Keys.Control;
            keys = keys & ~Keys.Alt;
            keys = keys & ~Keys.Shift;
            HotKey.Register(hWnd, mods, keys, callback);
        }

        /// <summary> 
        /// 注销快捷键 
        /// </summary> 
        /// <param name="hWnd">持有快捷键窗口的句柄</param> 
        /// <param name="callBack">回调函数</param> 
        public static void Unregister(IntPtr hWnd, HotkeyCallback callBack)
        {
            foreach (KeyValuePair<int, HotkeyCallback> var in keymap)
            {
                if (var.Value == callBack)
                    UnregisterHotKey(hWnd, var.Key);
            }
        }

        /// <summary> 
        /// 快捷键消息处理 
        /// </summary> 
        public static void ProcessHotKey(System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_HOTKEY)
            {
                int id = m.WParam.ToInt32();
                HotkeyCallback callback;
                if (keymap.TryGetValue(id, out callback))
                {
                    callback();
                }
            }
        }
    }

    enum HotKeyModifiers
    {
        MOD_ALT = 0x1,
        MOD_CONTROL = 0x2,
        MOD_SHIFT = 0x4,
        MOD_WIN = 0x8
    }
}
